use super::*;
use crate::sql_gen::{SqlGenerator, QueryType};

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn test_ai_engine_creation() {
        let engine = AiEngine::new();
        assert!(engine.sql_generator.patterns.len() > 0);
    }

    #[test]
    fn test_sql_generator_creation() {
        let generator = SqlGenerator::new();
        assert!(generator.patterns.len() > 0);
        assert!(generator.patterns.contains_key("find_all"));
        assert!(generator.patterns.contains_key("find_by_id"));
        assert!(generator.patterns.contains_key("count_all"));
    }

    #[tokio::test]
    async fn test_simple_select_generation() {
        let generator = SqlGenerator::new();
        let result = generator.generate("find all users", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("select"));
        assert!(result.sql.to_lowercase().contains("user"));
        assert!(result.confidence > 0.5);
        assert_eq!(result.query_type, QueryType::Select);
    }

    #[tokio::test]
    async fn test_count_query_generation() {
        let generator = SqlGenerator::new();
        let result = generator.generate("count all users", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("count"));
        assert!(result.sql.to_lowercase().contains("user"));
        assert!(result.confidence > 0.8);
        assert_eq!(result.query_type, QueryType::Select);
    }

    #[tokio::test]
    async fn test_insert_query_generation() {
        let generator = SqlGenerator::new();
        let result = generator.generate("add new user", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("insert"));
        assert!(result.sql.to_lowercase().contains("user"));
        assert!(result.confidence > 0.5);
        assert_eq!(result.query_type, QueryType::Insert);
    }

    #[tokio::test]
    async fn test_update_query_generation() {
        let generator = SqlGenerator::new();
        let result = generator.generate("update user information", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("update"));
        assert!(result.sql.to_lowercase().contains("user"));
        assert!(result.confidence > 0.5);
        assert_eq!(result.query_type, QueryType::Update);
    }

    #[tokio::test]
    async fn test_delete_query_generation() {
        let generator = SqlGenerator::new();
        let result = generator.generate("delete user record", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("delete"));
        assert!(result.sql.to_lowercase().contains("user"));
        assert!(result.confidence > 0.5);
        assert_eq!(result.query_type, QueryType::Delete);
    }

    #[tokio::test]
    async fn test_complex_select_with_conditions() {
        let generator = SqlGenerator::new();
        let result = generator.generate("find users where age > 18", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("select"));
        assert!(result.sql.to_lowercase().contains("user"));
        assert!(result.sql.to_lowercase().contains("where"));
        assert!(result.confidence > 0.5);
        assert_eq!(result.query_type, QueryType::Select);
    }

    #[tokio::test]
    async fn test_query_with_limit() {
        let generator = SqlGenerator::new();
        let result = generator.generate("find first 10 users", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("select"));
        assert!(result.sql.to_lowercase().contains("user"));
        assert!(result.sql.to_lowercase().contains("limit"));
        assert!(result.confidence > 0.5);
        assert_eq!(result.query_type, QueryType::Select);
    }

    #[tokio::test]
    async fn test_query_with_order_by() {
        let generator = SqlGenerator::new();
        let result = generator.generate("find users order by name", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("select"));
        assert!(result.sql.to_lowercase().contains("user"));
        assert!(result.sql.to_lowercase().contains("order by"));
        assert!(result.confidence > 0.5);
        assert_eq!(result.query_type, QueryType::Select);
    }

    #[tokio::test]
    async fn test_aggregation_query() {
        let generator = SqlGenerator::new();
        let result = generator.generate("average age of users", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("avg"));
        assert!(result.sql.to_lowercase().contains("user"));
        assert!(result.confidence > 0.5);
        assert_eq!(result.query_type, QueryType::Select);
    }

    #[tokio::test]
    async fn test_table_name_extraction() {
        let generator = SqlGenerator::new();
        
        // Test with common table names
        let result1 = generator.generate("find all customers", None).await.unwrap();
        assert!(result1.suggested_tables.contains(&"customer".to_string()));
        
        let result2 = generator.generate("show products", None).await.unwrap();
        assert!(result2.suggested_tables.contains(&"product".to_string()));
        
        let result3 = generator.generate("list orders", None).await.unwrap();
        assert!(result3.suggested_tables.contains(&"order".to_string()));
    }

    #[tokio::test]
    async fn test_low_confidence_warning() {
        let generator = SqlGenerator::new();
        let result = generator.generate("xyz abc def", None).await.unwrap();
        
        // Should have low confidence for unclear prompts
        assert!(result.confidence < 0.7);
        assert!(!result.warnings.is_empty());
        assert!(result.warnings.iter().any(|w| w.contains("Low confidence")));
    }

    #[tokio::test]
    async fn test_schema_context_integration() {
        let generator = SqlGenerator::new();
        let schema = "CREATE TABLE employees (id INT, name VARCHAR(100), department VARCHAR(50));";
        
        let result = generator.generate("find all employees", Some(schema)).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("select"));
        assert!(result.sql.to_lowercase().contains("employee"));
        assert!(result.suggested_tables.contains(&"employees".to_string()));
    }

    #[test]
    fn test_query_type_serialization() {
        use serde_json;
        
        let query_type = QueryType::Select;
        let serialized = serde_json::to_string(&query_type).unwrap();
        let deserialized: QueryType = serde_json::from_str(&serialized).unwrap();
        
        assert_eq!(query_type, deserialized);
    }

    #[test]
    fn test_generated_sql_serialization() {
        use serde_json;
        use crate::sql_gen::GeneratedSql;
        
        let generated_sql = GeneratedSql {
            sql: "SELECT * FROM users;".to_string(),
            explanation: "Test query".to_string(),
            confidence: 0.9,
            warnings: vec!["Test warning".to_string()],
            suggested_tables: vec!["users".to_string()],
            query_type: QueryType::Select,
        };
        
        let serialized = serde_json::to_string(&generated_sql).unwrap();
        let deserialized: GeneratedSql = serde_json::from_str(&serialized).unwrap();
        
        assert_eq!(generated_sql.sql, deserialized.sql);
        assert_eq!(generated_sql.confidence, deserialized.confidence);
        assert_eq!(generated_sql.query_type, deserialized.query_type);
    }

    #[tokio::test]
    async fn test_ai_engine_generate_sql() {
        let engine = AiEngine::new();
        let result = engine.generate_sql("find all users", None).await.unwrap();
        
        assert!(result.sql.to_lowercase().contains("select"));
        assert!(result.confidence > 0.0);
        assert!(!result.explanation.is_empty());
    }

    #[test]
    fn test_ai_engine_default() {
        let engine1 = AiEngine::new();
        let engine2 = AiEngine::default();
        
        // Both should have the same number of patterns
        assert_eq!(engine1.sql_generator.patterns.len(), engine2.sql_generator.patterns.len());
    }
}
